﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using Sausage.Common;
using Sausage.Web.DataModel;
using Sausage.Web.Models;

namespace Sausage.Web.Domain
{
    public static class MaterialHelper
    {
        public static IEnumerable<TreeNodeData> QueryMaterialTree()
        {
            using (var context = new SausageEntities())
            {
                return GetChildren(null, context.Material.ToList());
            }
        }

        private static IEnumerable<TreeNodeData> GetChildren(Guid? parentID, IEnumerable<Material> materialList)
        {
            var children = from material in materialList
                           where material.ParentID == parentID
                           select
                               new TreeNodeData
                                   {
                                       id = material.MaterialID,
                                       expanded = false,
                                       leaf = material.IsLeaf,
                                       name = material.MaterialName,
                                       parentID = material.ParentID,
                                       unit = material.Unit,
                                       pinyin = material.MaterialPinYin,
                                       data = GetChildren(material.MaterialID, materialList)
                                   };

            return children;
        }

        public static Material GetMaterialByID(Guid id)
        {
            using (var context = new SausageEntities())
            {
                return context.Material.FirstOrDefault(material => material.MaterialID == id);
            }
        }

        public static DeleteResult DeleteMaterial(Guid id)
        {
            using (var context = new SausageEntities())
            {
                var material = context.Material.FirstOrDefault(item => item.MaterialID == id);
                if(material == null || !material.IsLeaf)
                    return DeleteResult.Ok;

                //just delete the leaf node.
                if(material.ParentID.HasValue)
                {
                    var brothers = context.Material.Where(item => item.ParentID == material.ParentID).ToList();
                    if (brothers.Count <= 1)
                    {
                        var parent = context.Material.FirstOrDefault(item => item.MaterialID == material.ParentID.Value);
                        if (parent != null)
                            parent.IsLeaf = true;
                    }
                }

                context.ObjectStateManager.ChangeObjectState(material, EntityState.Deleted);
                try
                {
                    context.SaveChanges();
                }
                catch (UpdateException)
                {
                    return DeleteResult.UsingError;
                }
                return DeleteResult.Ok;
            }
        }

        public static void UpdateMaterial(TreeNodeData data)
        {
            using (var context = new SausageEntities())
            {
                var material = context.Material.FirstOrDefault(item => item.MaterialID == data.id);
                if (material== null)
                    return;

                material.MaterialName = data.name;
                material.MaterialPinYin = data.pinyin;
                material.Unit = data.unit;

                context.SaveChanges();
            }
        }

        public static Material GetMaterialByName(string name)
        {
            using (var context = new SausageEntities())
            {
                return context.Material.FirstOrDefault(material => material.MaterialName == name);
            }
        }

        public static void CreateMaterial(TreeNodeData data)
        {
            using (var context = new SausageEntities())
            {
                var material = new Material();

                material.MaterialID = Guid.NewGuid();
                material.ParentID = data.parentID;
                material.MaterialName = data.name;
                material.MaterialPinYin = data.pinyin;
                material.Unit = data.unit;
                material.TheOrder = 0;
                material.IsLeaf = true;

                if (data.parentID.HasValue)
                {
                    var parent = context.Material.FirstOrDefault(item => item.MaterialID == data.parentID.Value);
                    parent.IsLeaf = false;
                }

                context.AddToMaterial(material);
                context.SaveChanges();
            }
        }
    }
}